﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Axe.Workflow
{

    public delegate void TimerTaskDelegate();

    public class PeriodicalExecuterTask : ThreadTask
    {
        Dictionary<TimerTaskDelegate, DateTime> m_AAA = new Dictionary<TimerTaskDelegate, DateTime>();

        public PeriodicalExecuterTask()
            : base()
        {

        }

        public bool AddPeriodicTask(TimerTaskDelegate delTask,TimeSpan span, bool makeBackground)
        {
            lock (this)
            {
                if (m_AAA.ContainsKey(delTask))
                    return false;

                m_AAA.Add(delTask, DateTime.UtcNow - span); // For immediate call

                ThreadStart start = new ThreadStart
                    (
                        delegate() { TimerFunction(delTask, span); }
                    );

                base.AddParallelTask(start, makeBackground);
            }
            return true;
        }

        [ThreadStatic]
        DateTime m_LastCallTime = DateTime.UtcNow;

        void TimerFunction(TimerTaskDelegate del, TimeSpan span)
        {
            DateTime lastCall = m_LastCallTime;
            DateTime timeNow = DateTime.UtcNow;

            TimeSpan elapsed = timeNow - lastCall;

            if (elapsed < span)
            {
                TimeSpan deltha = span - elapsed;
                deltha = TimeSpan.FromMilliseconds(Math.Max(0, deltha.TotalMilliseconds));
                Thread.Sleep(deltha);
            }

            del(); // Call method

            m_LastCallTime = DateTime.UtcNow;
        }
    }
}
